package com.ayf.payment.game.api.service.payment;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.HttpHelper;
import com.ayf.payment.game.api.channel.jiabei.util.StringHelper;
import com.ayf.payment.game.api.dto.OrderAndMerchantDTO;
import com.ayf.payment.game.api.dto.platform.MerchantPaymentProductDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.entity.Partition;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.service.payment.util.PackageHtmlPayementFormUtil;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.Md5Utils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * 龙宝
 *
 * @author wwl
 * @description:
 * @date 2020/5/14 15:18
 */
@Service
public class LBPaymentService extends IPaymentService {

    @Override
    public Map<String, Object> paymentUtil(Order order, Partition partition, String orderCreateStr, String traceId, String redirectUrl) {
        traceId = "龙宝创建订单".concat(traceId);
        Map<String, Object> result = new HashMap<>(3);
        MerchantPaymentProductDTO merchantPaymentProductDTO = systemInitialization.productDTO(order.getPayTypeId());
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(merchantPaymentProductDTO.getcId());
        BigDecimal actualOrderAmt = getActualOrderAmt(order.getAmount(),paymentChannelDTO.getId(),partition.getMerchantId());
        String resultCode = orderCreate(order, traceId, redirectUrl,actualOrderAmt,merchantPaymentProductDTO,paymentChannelDTO);
        if (resultCode == null) {
            throw new NullSetException(traceId + " 下单失败，请稍后重试！");
        }
        if (resultCode.indexOf("payform") > 0) {
            order.setRandomAmt(BigDecimal.ZERO);
            order.setOrderNo("");
            order.setPayChannleName(paymentChannelDTO.getName());
            order.setPayChannleId(paymentChannelDTO.getId());
            order.setPayTypeId(merchantPaymentProductDTO.getProductId());
            order.setPayTypeName(merchantPaymentProductDTO.getProductName());
            order.setMerchantIncome(BigDecimal.ZERO);
            order.setPlatformIncome(BigDecimal.ZERO);
            order.setFee(BigDecimal.ZERO);
            order.setChannelIncome(BigDecimal.ZERO);
            orderMapper.insertSelective(order);
            result.put("code", "002");
            result.put("htmlMsg", resultCode);
        } else {
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        return result;
    }

    private String orderCreate(Order order, String traceId, String redirectUrl,BigDecimal actualOrderAmt,MerchantPaymentProductDTO merchantPaymentProductDTO,PaymentChannelDTO paymentChannelDTO) {
        String KeyValue = paymentChannelDTO.getChannelKey();
        String parter = paymentChannelDTO.getAccountNumber();
        String channelPayUrl = paymentChannelDTO.getPaymentUrl();
        String returnUrl = paymentChannelDTO.getReturnUrl();
        if (StringUtils.isEmpty(channelPayUrl)){
            LogPortal.error("{} 失败，通道下单地址不能为空，订单号:{}",traceId,order.getMerchantOrderNo());
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        if (!channelPayUrl.endsWith("/")){
            channelPayUrl=channelPayUrl.concat("/");
        }
        if (StringUtils.isEmpty(returnUrl)){
            LogPortal.error("{} 失败，异步通知地址不能为空，订单号:{}",traceId,order.getMerchantOrderNo());
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        if (!returnUrl.endsWith("/")){
            returnUrl=returnUrl.concat("/");
        }
        returnUrl=returnUrl.concat("gameapip/v/longbao/pay/");
        StringBuffer dicStr = new StringBuffer();
        dicStr.append("parter=").append(parter);
        dicStr.append("&type=").append(getPayCode(merchantPaymentProductDTO.getBusinessCode()));
        dicStr.append("&value=").append(actualOrderAmt); //单位元（人民币），2位小数，最小支付金额为0.02
        dicStr.append("&orderid=").append(order.getMerchantOrderNo());
        dicStr.append("&callbackurl=").append(returnUrl.concat("notify"));
        String sign = Md5Utils.md5(dicStr.toString() + KeyValue);

        Map<String,String> reqParam = new HashMap<>();
        reqParam.put("parter",parter);
        reqParam.put("type",getPayCode(merchantPaymentProductDTO.getBusinessCode()));
        reqParam.put("value",String.valueOf(actualOrderAmt));
        reqParam.put("orderid",order.getMerchantOrderNo());
        reqParam.put("callbackurl",returnUrl.concat("notify"));
        reqParam.put("hrefbackurl",returnUrl.concat("returns"));
        reqParam.put("payerIp",order.getClientIp());
        reqParam.put("attach",redirectUrl);
        reqParam.put("sign",sign);
        reqParam.put("agent","");

        String payFormHmtl = PackageHtmlPayementFormUtil.packageHtmlPayementForm(reqParam,channelPayUrl.concat("gateway/paybank"));
        LogPortal.info("{} 商户ID[{}] 商户订单号[{}] 请求报文[{}]",traceId,order.getMerchantId(),order.getMerchantOrderNo(),payFormHmtl);
        return payFormHmtl;
    }

    @Override
    public void queryPayOrder(OrderAndMerchantDTO dto, String traceId) {
        try {
            PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(dto.getPayChannleId());
            String KeyValue = paymentChannelDTO.getChannelKey();
            String resultCode = queryCreate(dto.getMerchantId(), dto.getMerchantOrderNo(), traceId, paymentChannelDTO);
            Map<String, String> map = formatResultStr(resultCode);
            if (map.isEmpty()) {
                LogPortal.error("{}龙宝订单查询失败，返回参数为空，商户订单号:{}",traceId,dto.getMerchantOrderNo());
                return;
            }
            String orderid = map.get("orderid");
            String parter = map.get("opstate");
            String ovalue = map.get("ovalue");

            String signVer = MessageFormat.format("orderid={0}&opstate={1}&ovalue={2}{3}", orderid, parter,ovalue, KeyValue);
            String signs= Md5Utils.md5(signVer);
            String sign = map.get("sign");
            if (sign.trim().equals(signs)) {
                Order order = orderService.selectByMerchantOrderNo(orderid);
                if (order == null) {
                    LogPortal.error("{} 龙宝订单查询 商户订单号[{}]在我方系统查询不到", traceId, orderid);
                    return;
                }
                OrderStatus orderStatus= OrderStatus.PROCESSING;
                if ("2".equals(parter)) {
                    LogPortal.error("{} 龙宝订单查询 商户订单号[{}] 签名错误",traceId, orderid);
                    return;
                }
                if ("8".equals(parter)) {
                    LogPortal.error("{} 龙宝订单查询 商户订单号[{}] 请求参数无效", traceId, orderid);
                    return;
                }
                if ("0".equals(parter)) {
                    orderStatus= OrderStatus.SUCCESS;
                }
                if (OrderStatus.PROCESSING.equals(order.getOrderStatus()) && !orderStatus.equals(OrderStatus.PROCESSING)) {
                    order.setOrderStatus(orderStatus);
                    order.setChannelRpsMsg(map.get("msg"));
                    orderService.paymentOrder(order, new JSONObject());
                    if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                        orderService.orderToGetWay(order);
                        wxSendMsgUtils.rechargeSuccess(order);
                    }
                }
            }
        } catch (Exception e) {
            LogPortal.error("{} 龙宝订单查询 发生{}异常，订单号:{}", e,traceId,e.getClass().getName(),dto.getMerchantOrderNo());
        }
    }

    private String queryCreate(Integer merId, String orderid, String traceId, PaymentChannelDTO paymentChannelDTO) {
        String MerhantId = paymentChannelDTO.getAccountNumber();
        String KeyValue = paymentChannelDTO.getChannelKey();
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
        StringBuffer dicStr = new StringBuffer();
        dicStr.append("orderid=").append(orderid);
        dicStr.append("&parter=").append(MerhantId);
        String sign = StringHelper.EncodeMD5(dicStr.toString() + KeyValue);
        dicStr.append("&sign=").append(sign);
        LogPortal.info("{} 龙宝订单查询 商户ID[{}] 商户订单号[{}] 请求参数[{}]",traceId,merId,orderid,dicStr.toString());
        String result = "";
        try {
            //请求上游接口
            result = HttpHelper.sendPost2(AuthorizationURL + "/gateway/search", dicStr.toString(), traceId);
            LogPortal.info("{} 龙宝订单查询 返回结果[{}]", traceId,result);
        } catch (Exception e) {
            LogPortal.error("{} 龙宝订单查询失败 发生了{}异常，错误描述:{}",e,traceId,e.getClass().getName(),e.getMessage());
        }
        return result;
    }

    private Map formatResultStr(String result) {
        Map<String, String> map = new HashMap<>(4);
        String[] strArray1 = result.split("&");
        for (String str : strArray1) {
            String[] strArray = str.split("=");
            map.put(strArray[0], strArray[1]);
        }
        return map;
    }

    private String getPayCode(String code) {

        if ("ALIPAY".equals(code) || "ANTCREDITPAY".equals(code)) {
            return "992";
        } else if ("WECHAT".equals(code)) {
            return "1004";
        } else {
            throw new NullSetException("该通道不支持充值，请更换其他通道充值！");
        }
    }
}
